// 我们自己的函数库（工具函数）

// 判断数组中是否有某个值
function has(arr,val){
    for (var i = 0; i < arr.length; i++){
        if (arr[i] === val) {
            return true;
        }
    }
    return false;
}

// 根据传入的key返回对应的参数值
function getQueryString(url,key){
    if (!key) {
        return '';
    }
   var reg = new RegExp('[\?&]'+key+'=([^&=]*)','g');
   reg.test(url);// 执行一次匹配，自动缓存分组匹配到的内容
   return RegExp.$1;
}

// 生成指定区间的随机整数
function randomInt(min,max){
    return Math.round( Math.random()*(max-min)+min );
}

// 随机生成十六进制颜色
function randomColor(){
    var color = '#';
    var str = '0123456789abcdef';// 长度16 索引0-15
    for (var i = 0; i < 6; i++){
        // 每次循环时,生成一个0-15的随机整数,作为索引
        var index = randomInt(0,15);
        color += str[index];// 与#号拼接
    }
    return color;
}

// 随机生成x位验证码
function randomCode(x){
    x = x || 6;// 设置参数默认值为 6
    var code = '';
    // 循环执行一次,生成一个随机字符
    for (var i = 0; i < x; i++){
        do{
            // 先生成随机整数,再判断是否在合法范围内
            var num = randomInt(48,122);// 随机整数
        }while( (num >=58&&num<=64) || (num >= 91&&num<=96) );
        var str = String.fromCharCode(num);// 根据随机整数转成对应字符
        code += str;// 字符串拼接
    }
    return code;// 返回值
}

// 封装获取元素的函数
function $1(selector){// 返回单个元素
    return document.querySelector(selector);
}
function $2(selector){// 返回元素集合
    return document.querySelectorAll(selector);
}
function $(selector){// 可以返回单个元素或元素集合
    var dom = document.querySelectorAll(selector);// 元素集合
    if (dom === null) {
        // 当前要获取的元素不存在
        return null;
    }
    if (dom.length > 1) {
        // 获取到多个元素
        return dom;
    } else {
        // 获取到一个元素
        return dom[0];
    }
}

// 获取元素样式（兼容IE678）
function getStyle(dom,attr){
    if (dom.currentStyle) {// dom.currentStyle === {...}
        // IE678
        return dom.currentStyle[attr];
    } else {// dom.currentStyle === undefined
        // 非IE678
        return getComputedStyle(dom)[attr];
    }
}

// 获取dom元素到页面的距离（body的距离）
function offset(dom){
    var offset_left = 0 - dom.clientLeft;
    var offset_top = 0 - dom.clientTop;
    // 将dom的左边框和offsetLeft + 它定位父级的左边框和offsetLeft 。。。
    while(dom){
        offset_left += dom.clientLeft + dom.offsetLeft;
        offset_top += dom.clientTop + dom.offsetTop;
        dom = dom.offsetParent;
    }
    return {left: offset_left, top: offset_top};
}

// 添加事件监听（兼容低本版IE）
function addEvent(dom,type,callback){
    if (dom.addEventListener) {
      dom.addEventListener(type,callback);
    } else {
      dom.attachEvent('on'+type,callback);
    }
}

// 移除事件监听（兼容低本版IE）
function removeEvent(dom,type,callback){
    if (dom.removeEventListener) {
      dom.removeEventListener(type,callback);
    } else {
      dom.detachEvent('on'+type,callback);
    }
}

/**
 * animate 运动函数
 * 参数说明：
 *  params dom {object} 要运动的元素
 *  params attr {string} 要运动的css属性
 *  params target {number} 运动的目标位置
 *  params callback {function} 运动完成之后的回调函数，可选
 * 
 * 功能说明：
 *  1.支持带px单位的属性运动，如left top width height marginLeft fontSize ...
 *  2.支持透明度opacity
 *  3.滚动条scrollLeft/scrollTop运动
 */
 function animate(dom,attr,target,callback){
    // 获取当前值
    if (attr === 'opacity') {
        // 因为透明的值范围是0-1，可运动的区间太小，不适合执行动画
        // 所以，将当前值乘以100之后再执行运动
        var current = getComputedStyle(dom)[attr] * 100;
        target = target * 100;
        // 100 --> 10
    } else if (attr === 'scrollLeft' || attr === 'scrollTop'){
        var current = dom[attr];
    } else {
        var current = parseFloat( getComputedStyle(dom)[attr] );// 当前值'10px' -> 10
    }

    clearInterval(dom.timer);// 先清除计时器，保证不会出现计时器叠加
    // 给dom添加timer属性记录计时器编号
    dom.timer = setInterval(function (){
        // 持续变化的速度
        var speed = (target-current)/12;

        // 判断方向并对速度取整
        speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);

        // 当前位置累加速度
        current += speed;

        // 判断是否到达目标位置(剩余运动量<=每次的运动量)
        if (Math.abs(target-current) <= Math.abs(speed)) {// 到达目标位置
            clearInterval(dom.timer);// 运动停止
            // 立即到达目标位置
            if (attr === 'opacity') {
                dom.style[attr] = target/100;
            } else if (attr === 'scrollLeft' || attr === 'scrollTop'){
                dom[attr] = target;
            } else {
                dom.style[attr] = target + 'px';
            }
            // console.log( '到达目标位置。。。' );
            // if (typeof callback === 'function') {
            //     callback();// 运动完成之后执行回调函数
            // }
            typeof callback === 'function' && callback();
        } else {// 没到达目标位置
            // 改变dom的当前位置
            if (attr === 'opacity') {
                dom.style[attr] = current/100;
            } else if (attr === 'scrollLeft' || attr === 'scrollTop'){
                dom[attr] = current;
            } else {
                dom.style[attr] = current + 'px';
            }
        }
    },20);
}